<?php

class UserAuthenticatorComponent extends Object {

    //called before Controller::beforeFilter()
    function initialize(&$controller, $settings = array()) {
        // saving the controller reference for later use
        $this->controller = & $controller;
    }

    //called after Controller::beforeFilter()
    function startup(&$controller) {

    }

    //called after Controller::beforeRender()
    function beforeRender(&$controller) {
        
    }

    //called after Controller::render()
    function shutdown(&$controller) {

    }

    //called before Controller::redirect()
    function beforeRedirect(&$controller, $url, $status=null, $exit=true) {
        
    }

    function redirectSomewhere($value) {
        // utilizing a controller method
        $this->controller->redirect($value);
    }

    /**
     * This function uses Acl and Auth components to decide if
     * the requested action on requested controller is allowed to the
     * logged in user.
     * If the action is allowed, this function will return true.
     * If the action is not allowed, this function returns false.
     *    and if he user was not logged in, he is redirected to login page.
     *    and if the user was already logged in, a message is set to be flashed "Permission Denied.".
     * @return <type>
     */
    function checkAccess() {


        // This part not required. It shows one way to
        // integrate this permission with authentication: login/logout
        // We always put the login_name in the session under
        // the key USER_LOGIN_KEY, even for anonymous users.
        // So whether a user is logged in or not depends on
        // whether this value is ANONY_USER or not. You may
        // choose to implement it some other way (e.g., whether it's
        // set or not.)
        if (!$this->controller->Session->valid()) {
            $this->controller->Session->renew();
        }
        if (!$this->controller->Session->check('Auth.User')) {
            $this->controller->Session->write('Auth.User', 'ANONY_USER');
        }



        // here we check the permissions based on
        // username and controller name (which is
        // is the first part of the URL)
        //Do not use $this->Session->read('USER_LOGIN_KEY');
        //Seems like, AuthComponent does not set this Session key
        //It sets Auth.User.
        //So, use $this->Session->read('Auth.User');
        $auth_user = $this->controller->Session->read('Auth.User');

        // if anonymous, redirect to login
        if ($auth_user == 'ANONY_USER') {
            //When there is no group, we need to temporarily allow access through code
//            return true;
            $this->controller->Session->setFlash("user_authenticator.php: U r not logged in. Please login first.");
            $this->controller->redirect("/users/login");

            //$this->controller->redirect("/pages/permission_denied");
            //If the user is not anonymous, but userId is not available in $auth_user
            //then there is some problem. Anyways, in that case we cannot verify the permissions.
            //so just deny access to be on safe side.
        } else if (!is_array($auth_user) || !isset($auth_user['id'])) {

            $this->controller->Session->setFlash("Permission denied");
            return false;


            //If the user is logged in
            //check the access
        } else if (is_array($auth_user) || isset($auth_user['id'])) {

            $username = $auth_user['username'];
            $userId = $auth_user['id'];

            //check access.
            if ($this->isActionAllowed($userId)) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * If the action is allowed to the logged in user, true returned.
     * If the user has not logged in yet, false is returned.
     * @param String $userId (Such that "User:<$userId>" forms alias in aros table.
     * @return boolean true if action allowed. Else false.
     */
    function isActionAllowed($userId) {

        //$aro is the requestor object.
        //$aco is the object requested.
        //We are going to check if $aro is allowed access to $aco using cakephp's AclComponent.
        //Please note that $aro should have the value
        //of the alias field of the aro record
        //in the aros table.
        $aro = "User:" . $userId;

        //Please note that $aco should have the value of the alias field of the
        //aco record in the acos table.
        $aco = $this->controller->params['action'];
        $isAllowed = $this->controller->Acl->check($aro, $aco, '*');

        return $isAllowed;
    }

    /**
     *
     * @return (int) id of the user in users table
     */
    function getLoggedInUserId() {
        $userId = -1;
        $auth_user = $this->controller->Session->read('Auth.User');
        //If the user is logged in
        if (is_array($auth_user) || isset($auth_user['id'])) {

            $username = $auth_user['username'];
            $userId = $auth_user['id'];

        }
        return $userId;
    }

}

?>